<template>
  <h1>{{ msg }} :{{ state.title }}</h1>
  <h1>这是解构state出来的title ： {{title }}</h1>
 title: <input v-model="title"/>
  <br/>
  <input type="text" v-model="state.num1"/>
  <select v-model="state.mark">
    <option v-for="(item,index) in state.markList" :value="item" :key="index"> {{ item }}</option>
  </select>
  <input type="text" v-model="state.num2"/>
  =
  <input type="text" readonly :value="state.result" @change="handleChange($event)"/>


  <button @click="onChangeMsg">改变props中的msg，看看是否能够变化</button>
</template>

<script lang="ts">
// props 的推断类型；
interface Data {
  [key: string]: unknown
}

import {defineComponent, reactive, computed, inject, watchEffect, SetupContext,toRefs} from 'vue'

export default defineComponent({
  name: 'HelloWorld',
  props: {
    //string类型
    msg: {
      type: String,
      default: '',
      required: true
    },
    msg2: String,
    // 对象类型
    obj: {
      type: Object,
      default() {
        return {}
      }
    },
    // 数组类型
    array: {
      type: Array,
      default() {
        return []
      }
    },
    //这种定义是错的。可以看到default的返回值是unknown
    array2: {
      type: Array,
      default: []
    },
    // boolean类型
    isBoolean: {
      type: Boolean,
      default: true
    },
    // 方法；无返回值；
    rowClick: {
      type: Function,
      default() {

      }
    },
    // 方法：有返回值
    resultFunction: {
      type: Function,
      default() {
        return "resultFunction"
      }
    }
  },
  //子组件必须定义emits的所有方法名，不写，不会出错。但是会有警告
  emits: ['onCtoF'],
  setup: (props: Data, ctx:SetupContext) => {
    // 定义一个响应式的对象; set,get不需要使用value属性，直接可以使用；
    const state: any = reactive({
      num1: 0,
      num2: 0,
      mark: '+',
      markList: ['+', '-', '*', '/'],
      result: computed(() => {
        const value = computedFun()
        ctx.emit('onCtoF', value)
        return value
      }),
      title: inject('title')
    })

    const computedFun = () => {
      switch (state.mark) {
        case '+':
          return Number(state.num1) + Number(state.num2)
        case "-":
          return Number(state.num1) - Number(state.num2)
        case "*":
          return Number(state.num1) * Number(state.num2)
        case "/":
          return Number(state.num2) === 0 ? 0 : Number(state.num1) / Number(state.num2)
        default:
          return 0
      }
    }

    //@change无法监听到，非手动输入的变化，所以这边无法得到值；
    const handleChange = (event: any) => {
      console.log(event)

    }

    watchEffect(() => {
      console.log(props.msg)
    })

    const onChangeMsg = () => {
      console.log(props.msg)
    }

    setTimeout(()=>{
      state.title = "这是变化后的"
    },1000)

    return {
      state,
      handleChange,
      onChangeMsg,
      ...toRefs(state) // 依然是响应式的
    }
  }
})
</script>

<style scoped>
a {
  color: #42b983;
}

label {
  margin: 0 0.5em;
  font-weight: bold;
}

code {
  background-color: #eee;
  padding: 2px 4px;
  border-radius: 4px;
  color: #304455;
}
</style>
